# -*- coding: UTF-8 -*-
"""
@File ：product_uom
@Author ：lucas
@Date ：2023-10-18 23:06:00
@Description: 
"""

import logging
from odoo import api, fields, models
from odoo.exceptions import UserError, ValidationError
from odoo.tools.float_utils import float_compare, float_round

_logger = logging.getLogger(__name__)

UOM_TYPES = [('bigger', '大于基准分类'), ('reference', '分类基准单位'), ('smaller', '小于基准分类')]


class ProductUoM(models.Model):
    _name = 'justdoo.product.uom'
    _description = '产品单位'

    name = fields.Char('名称', required=True)
    uom_note = fields.Char(string='说明')
    category_id = fields.Many2one('justdoo.uom.category', '分类', required=True, ondelete='restrict')
    factor = fields.Float('单位比例', default=1.0, digits=(16, 6), required=True, help='大于或小于基准分类的倍数')
    rounding = fields.Float('舍入精度', default=0.01, digits=(16, 6), required=True)
    active = fields.Boolean('启用', default=True)
    uom_type = fields.Selection(UOM_TYPES, '单位类型', default='reference', required=True)
    company_name = fields.Char('公司', default=lambda self: self.env.company.name)
    company_id = fields.Integer('公司ID', default=lambda self: self.env.company.id)

    _sql_constraints = [
        ('factor_check', 'CHECK (factor>0)', '转换比例必须是一个正数'),
        ('rounding_check', 'CHECK (rounding>=0 and rounding<1)', '舍入精度必须是一个正数')
    ]

    @api.constrains('rounding')
    def _check_uom_rounding(self):
        precision = self.env['decimal.precision'].precision_get('Justdoo.Product.UOM')
        for uom in self:
            if uom.rounding == 0.0 or uom.rounding >= 1.0 / 10.0 ** precision:
                continue
            raise ValidationError('当前单位舍入精度已经大于标准产品单位精度，这可能导致计算结果不一致，请修改此舍入精度！')

    def check_category_reference_uniqueness(self):
        for uom in self:
            category = uom.category_id
            if not category.uom_lines:
                continue
            reference_count = sum(uom.uom_type == 'reference' for uom in category.uom_lines)
            if reference_count > 1:
                raise ValidationError("单位分类 %s 只能有一个基准单位" % category.name)
            elif reference_count == 0:
                raise ValidationError("单位分类 %s 必须要有一个基准单位" % category.name)

    @api.model_create_multi
    def create(self, value_list):
        for value in value_list:
            if value['uom_type'] != 'reference':
                continue
            value['factor'] = 1.0
        uom_list = super().create(value_list)
        uom_list.check_category_reference_uniqueness()
        return uom_list

    def write(self, values):
        if 'uom_type' in values and values['uom_type'] == 'reference':
            values['factor'] = 1.0
        result = super().write(values)
        if 'uom_type' in values:
            self.check_category_reference_uniqueness()
        return result

    def compute_quantity(self, qty, to_unit, rounding=True, rounding_method='UP', raise_if_failure=True):
        self.ensure_one()
        if not to_unit:
            return qty
        if self != to_unit and self.category_id.id != to_unit.category_id.id:
            if raise_if_failure:
                raise UserError('单位%s和%s不在同一个分类下，不可以执行转换' % (self.name, to_unit.name))
            else:
                return qty
        # 转换成标准单位
        to_unit_qty = qty * self.factor if self.uom_type == 'bigger' else qty / self.factor
        # 标准单位转成目标单位
        to_unit_qty = to_unit_qty / to_unit.factor if to_unit.uom_type == 'bigger' else to_unit_qty * to_unit.factor
        if to_unit and rounding:
            to_unit_qty = float_round(to_unit_qty, precision_rounding=to_unit.rounding, rounding_method=rounding_method)
        return to_unit_qty
